/* File contains the code for reading thread of beacon node... */

#include "projectHeader.h"

void * beaconRead(void * t)
{
	int socketDesc = (int)t;

	//printf("\nINSIDE BEACON READ: Socket descriptor is : %d\n",socketDesc);
	//char* buff = "Hi i am sending from read";

	/*********************************************************************
	*
	*	Code for dispatcher thread here.
	*	Read from the socket and Write into read queue..	
	*
	**********************************************************************/
	
	/*
	char buff[512];
	int recv_ret=(int)recv(socketDesc,&buff,sizeof(buff),0);
	printf("\nReceived bytes : %d\n",recv_ret);
	if(recv_ret<0)
	{
		printf("Error in receieveing Hello Header.\n");
		exit(1);
	}
	printf("\nReceived string = %s\n",buff);
	*/



	

		//*******************************************Will be used later for KEEPALVIE TIMER..***********************************
		pthread_mutex_lock(&sockIndexMapMutex);
		int index=sockFDToQIndexMap[socketDesc];
		pthread_mutex_unlock(&sockIndexMapMutex);


	
	while(1)
	{
			msgHeaderClass readMsgHeader;

			int ret=(int)recv(socketDesc,&readMsgHeader,sizeof(msgHeaderClass),0);
			if(ret==0)
			{
				continue;
			}
			if(ret<0)
			{
					//perror("*******************************ERROR: error in recieveing join response in ReadThread.");
					//TODO: Do error Handling here..		
				
						//check message push
						if(!iAmBeacon)
						{
							queueItem statusReqToBePushed;
							statusReqToBePushed.sockfd=-1;
							statusReqToBePushed.msgHeader.messageType=0xF6;
//							printf("\n-----------1--------------\n");
							unsigned char* buff1=(unsigned char*)malloc(20*sizeof(unsigned char));
//							printf("\n-----------22222--------------%s\n",nodeInstanceId);
							char* msg = (char*)"CKRQ";
//							printf("\n-----------2--------------%s\n",msg);
							buff1=GetUOID((char *)nodeInstanceId,msg,buf, sizeof(buf));
							memcpy(&(statusReqToBePushed.msgHeader.UOID[0]),&buf[0],20);
//							printf("\n-----------3--------------\n");
							statusReqToBePushed.msgHeader.ttlInHeader=ttl;
							statusReqToBePushed.msgHeader.msgDataLength=0;
//							printf("\n-----------4--------------\n");

							//memcpy(&(statusReqToBePushed.dataBuf[0]),&(statusData.statusType),statusReqToBePushed.msgHeader.msgDataLength);


							if(noCheck==0)
							{
								pthread_mutex_lock(&eventQueueMutex);


							eventQueue.push_back(statusReqToBePushed);
							//printf("Read Thread:CHECK MSG Pushed to Event Dispatcher.\n");
							pthread_cond_broadcast(&eventQueueCV);


								pthread_mutex_unlock(&eventQueueMutex);
								//check timeout thread start
							//	pthread_create(&checkTimeOut,NULL,checkTimeOutThread,NULL);
							
								//join this thread
							//	pthread_join(checkTimeOut,NULL);
							}
					
						}

						
					
					

					pthread_exit(NULL);
			}
			
			if(readMsgHeader.messageType!=0xF8)
		{
				//printf("READ THREAD: Message type: 0X%2X\n",readMsgHeader.messageType);
		}
				//printf("READ THREAD: Message type: 0X%2X\n",readMsgHeader.messageType);
			//TODO: Handle keelalive timer here.
			pthread_mutex_lock(&keepAliveMapMutex);
				map<int,int>:: iterator temp;
				temp=keepAliveTimers.find(index);
				(*temp).second=keepAliveTimeOut;
			//printf("Msg detected. Keep Alive Timer reset for %d and time = %d\n",socketDesc,(*temp).second);
			pthread_mutex_unlock(&keepAliveMapMutex);
			//Recieve Data header.
			//printf("\n**********************************%d\n",readMsgHeader.msgDataLength);
		
			/*	If message is store message
				{
					store uoid and ttl into some variable
					cache the message into message cache
					
					calculate store probability
					if(prabability is true)
					{
						update index structure map
						store meta file 
						store the data file
						store into cache based
					}
				}
				(readMsgHeader type == 0xCC)
			*/
//=========================================GET RESP START========================================================
			if(readMsgHeader.messageType==0xDB)
			{
	//			printf("---------Read Thread: header is :\n");
	/*			printf("r STRS %d 0x%02x %x%x%x%x  on socket %d\n",
								(readMsgHeader.msgDataLength),
								(unsigned char)readMsgHeader.ttlInHeader,
								(unsigned char)readMsgHeader.UOID[16],
								(unsigned char)readMsgHeader.UOID[17],
								(unsigned char)readMsgHeader.UOID[18],
								(unsigned char)readMsgHeader.UOID[19],socketDesc);

				//decrement ttl here which is used for flooding below.
				if((readMsgHeader.ttlInHeader-1)<ttl)
				{
					readMsgHeader.ttlInHeader=readMsgHeader.ttlInHeader-1;
				}
				else
				{
					readMsgHeader.ttlInHeader=ttl;	
				}
				*/
				
				unsigned char readBuf[MAXFILEBUF];
				memset(&readBuf[0],0x00,MAXFILEBUF);
				
				unsigned char metaDataBuff[MAXFILEBUF];
				memset(&readBuf[0],0x00,MAXFILEBUF);
				map<string,msgLifeTimeClass>::iterator uoidIterator;
				string str ((const char*)readMsgHeader.UOID,20);

				pthread_mutex_lock(&UOIDMsgLifeTimeMapMutex);
				uoidIterator=UOIDMsgLifeTimeMap.find(str);
				bool isStored=false;
				//bool deleteTemp=false;
				if(uoidIterator == UOIDMsgLifeTimeMap.end())
				{
						unsigned char uoidToInsertInMap[20];
						memcpy(&uoidToInsertInMap[0],readMsgHeader.UOID,20);
						string uoid((const char*)uoidToInsertInMap,20);
						msgLifeTimeClass newEntry(socketDesc,msgLifeTime);
						//newEntry.sockOfMsgReciept=itemFromQueue.sockfd;
						//newEntry.msgLifeTimeValue=msgLifeTime;
						UOIDMsgLifeTimeMap.insert(pair<string,msgLifeTimeClass>(uoid,newEntry));

						//pthread_mutex_unlock(&UOIDMsgLifeTimeMapMutex);

						



						int fwdToSocket=0;
						char tempDataFile[256];
						char tempMetaFile[256];
						memset(tempDataFile, '\0', 256);
						memset(tempMetaFile, '\0', 256);
						pthread_mutex_lock(&tempfileindexlock);
						sprintf(tempDataFile, "%s/%d.data", homeDir, tempFileIndex);
						sprintf(tempMetaFile, "%s/%d.meta", homeDir, tempFileIndex);
						int temptempFileId=tempFileIndex++;
						pthread_mutex_unlock(&tempfileindexlock);
						int numfileId;
						char dataUOID[21];
						memset(&dataUOID[0],'\0',21);
/*					
						FILE *tempFData = fopen(tempDataFile, "w");
						FILE *tempFMeta = fopen(tempMetaFile, "w");
						printf("Recieve msg Header data length: %d\n",readMsgHeader.msgDataLength);*/
						if(readMsgHeader.msgDataLength<=MAXFILEBUF)
						{
							//char tempDataFile[256];
							//char tempMetaFile[256];
							/*memset(tempDataFile, '\0', 256);
							memset(tempMetaFile, '\0', 256);
							pthread_mutex_lock(&tempfileindexlock);
							sprintf(tempDataFile, "%s/%d.data", homeDir, tempFileIndex);
							sprintf(tempMetaFile, "%s/%d.meta", homeDir, tempFileIndex);
							int temptempFileId=tempFileIndex++;
							pthread_mutex_unlock(&tempfileindexlock);
							*/
							
				//			printf("Recieve msg Header data length: %d\n",readMsgHeader.msgDataLength);
							int retdata=(int)recv(socketDesc,&readBuf,readMsgHeader.msgDataLength,0);
							if(retdata<0)
							{
							}
							//printf("MetaLength is %X%X%X%X\n",readBuf[0],readBuf[1],readBuf[2],readBuf[3]);
							//printf("%s\n\n\n\n",readBuf);
							



						pthread_mutex_lock(&connectedNodeListMutex);
									uint16_t portTemp=0;
									char *tempHost=(char*)malloc(512);

								map<string,int>::iterator it;
								for(it=connectedNodeList.begin() ; it != connectedNodeList.end(); it++ )
								{
									if((*it).second==socketDesc)
									{
												char* str1 = (char*) malloc(512); 
												memset(&str1[0],'\0',512);
												memcpy(&str1[0],&(((*it).first).c_str()[0]),19);

												char *str=(char*)malloc(512);
												memset(str,'\0',512);
												memcpy(&str[0],&str1[0],strlen(str1));
												//printf("String from list is %s\n",str);
												
												tempHost=strtok(str,"_");
												//printf("TempHost is %s and length is %d\n",tempHost,(int)strlen(tempHost));
												char *tempPort=strtok(NULL,"_");
												//printf("TempPort is %s and length is %d\n",tempPort,(int)strlen(tempPort));
												
												portTemp=atoi(tempPort);
												break;
									}
								
								}
				pthread_mutex_unlock(&connectedNodeListMutex);

									pthread_mutex_lock(&logFileMutex);

										gettimeofday(&tv, NULL); 
										int sec = tv.tv_sec ;
										int msec = tv.tv_usec/1000;
										char *time = (char *)malloc(14);
										memset(time,0,14);
										sprintf(time,"%10ld.%03d",(long)sec,msec);
										time[strlen(time)]='\0';

										



										fprintf(logFilePtr, "r  %s %s:%hu GTRS %d 0x%02x %x%x%x%x %x%x%x%x\n",time,
											tempHost,
											portTemp,
											(readMsgHeader.msgDataLength+27),
											(unsigned char)readMsgHeader.ttlInHeader,
											(unsigned char)readMsgHeader.UOID[16],
											(unsigned char)readMsgHeader.UOID[17],
											(unsigned char)readMsgHeader.UOID[18],
											(unsigned char)readMsgHeader.UOID[19],
											(unsigned char)readBuf[16],
											(unsigned char)readBuf[17],
											(unsigned char)readBuf[18],
											(unsigned char)readBuf[19]);
											//helloRecvData.HostPort,helloRecvData.Hostname);
										pthread_mutex_unlock(&logFileMutex);











							int metalength;


							//pthread_mutex_lock(&UOIDMsgLifeTimeMapMutex);
							unsigned char uoidFromItemData[20];
							memcpy(&uoidFromItemData[0],&(readBuf[0]),20);
							memcpy(&dataUOID[0],&(readBuf[0]),20);
							
							string str1 ((const char*)uoidFromItemData,20);
							uoidIterator=UOIDMsgLifeTimeMap.find(str1);

							if(uoidIterator==UOIDMsgLifeTimeMap.end())
							{
						
								//NOT FOUND
								pthread_mutex_unlock(&UOIDMsgLifeTimeMapMutex);
								pthread_mutex_lock(&tempfileindexlock);
								//tempFileIndex--;
								pthread_mutex_unlock(&tempfileindexlock);
								continue;
								//printf("EVENT DISPATCHER: STATUS RESPONSE. THERE HAS NOT BEEN ANY STATUS REQ FOR THIS UOID.\n\n");
								
							}
							else
							{
								msgLifeTimeClass tmp=(*uoidIterator).second;
								fwdToSocket=tmp.sockOfMsgReciept;
							//	pthread_mutex_unlock(&UOIDMsgLifeTimeMapMutex);
								pthread_mutex_unlock(&UOIDMsgLifeTimeMapMutex);
								FILE *tempFData = fopen(tempDataFile, "w");
								FILE *tempFMeta = fopen(tempMetaFile, "w");
								memcpy(&metalength, &readBuf[20],4);
								//localmetalength = metalength;
								
								//printf("1 Read threaad Metadata length : %d\n", metalength);
								memcpy(&metaDataBuff[0],&readBuf[24],metalength);
								
								int r = fwrite(readBuf+24,1,metalength,tempFMeta);
								if (r == -1)
								{
									 //printf("Read thread: Error writing MEtafile\n");
								}

								//write the remainig data to datafile.
								r = fwrite(readBuf+24+metalength, 1,(readMsgHeader.msgDataLength) -(24+metalength),tempFData);
								if (r == -1)
								{
									 //printf("Read thread: Error writing Datafile-1\n");
								}
								fclose(tempFData);
								fclose(tempFMeta);
							}
						}// Maxbuf< over
						else
						{	

			
						
								int numberOfSegments = ceil((double)(readMsgHeader.msgDataLength)/MAXFILEBUF);
								int bytesToBeRead=MAXFILEBUF;
									int metalength;
									
						
									//char tempDataFile[256];
									//char tempMetaFile[256];
									/*memset(tempDataFile, '\0', 256);
									memset(tempMetaFile, '\0', 256);
									pthread_mutex_lock(&tempfileindexlock);
									sprintf(tempDataFile, "%s/%d.data", homeDir, tempFileIndex);
									sprintf(tempMetaFile, "%s/%d.meta", homeDir, tempFileIndex);
									int temptempFileId=tempFileIndex++;
									pthread_mutex_unlock(&tempfileindexlock);
									*/
									
								//	printf("Recieve msg Header data length: %d\n",readMsgHeader.msgDataLength);

									int retdata=(int)recv(socketDesc,&readBuf,bytesToBeRead,0);
									if(retdata<0)
									{
									}







								pthread_mutex_lock(&connectedNodeListMutex);
											uint16_t portTemp=0;
											char *tempHost=(char*)malloc(512);

										map<string,int>::iterator it;
										for(it=connectedNodeList.begin() ; it != connectedNodeList.end(); it++ )
										{
											if((*it).second==socketDesc)
											{
														char* str1 = (char*) malloc(512); 
														memset(&str1[0],'\0',512);
														memcpy(&str1[0],&(((*it).first).c_str()[0]),19);

														char *str=(char*)malloc(512);
														memset(str,'\0',512);
														memcpy(&str[0],&str1[0],strlen(str1));
														//printf("String from list is %s\n",str);
														
														tempHost=strtok(str,"_");
														//printf("TempHost is %s and length is %d\n",tempHost,(int)strlen(tempHost));
														char *tempPort=strtok(NULL,"_");
														//printf("TempPort is %s and length is %d\n",tempPort,(int)strlen(tempPort));
														
														portTemp=atoi(tempPort);
														break;
											}
										
										}
									pthread_mutex_unlock(&connectedNodeListMutex);

									pthread_mutex_lock(&logFileMutex);

										gettimeofday(&tv, NULL); 
										int sec = tv.tv_sec ;
										int msec = tv.tv_usec/1000;
										char *time = (char *)malloc(14);
										memset(time,0,14);
										sprintf(time,"%10ld.%03d",(long)sec,msec);
										time[strlen(time)]='\0';

										



										fprintf(logFilePtr, "r  %s %s:%hu GTRS %d 0x%02x %x%x%x%x %x%x%x%x\n",time,
											tempHost,
											portTemp,
											(readMsgHeader.msgDataLength+27),
											(unsigned char)readMsgHeader.ttlInHeader,
											(unsigned char)readMsgHeader.UOID[16],
											(unsigned char)readMsgHeader.UOID[17],
											(unsigned char)readMsgHeader.UOID[18],
											(unsigned char)readMsgHeader.UOID[19],
											(unsigned char)readBuf[16],
											(unsigned char)readBuf[17],
											(unsigned char)readBuf[18],
											(unsigned char)readBuf[19]);
											//helloRecvData.HostPort,helloRecvData.Hostname);
										pthread_mutex_unlock(&logFileMutex);











									memcpy(&metalength, &readBuf[20],4);
									memcpy(&metaDataBuff[0],&readBuf[24],metalength);
								//	printf("Read threaad Metadata length : %d\n", metalength);
									//pthread_mutex_lock(&UOIDMsgLifeTimeMapMutex);
									unsigned char uoidFromItemData[20];
									memcpy(&uoidFromItemData[0],&(readBuf[0]),20);
									memcpy(&dataUOID[0],&(readBuf[0]),20);
									
									string str1 ((const char*)uoidFromItemData,20);
									uoidIterator=UOIDMsgLifeTimeMap.find(str1);
									int remainingDataToBeRead = readMsgHeader.msgDataLength-MAXFILEBUF;
									if(uoidIterator==UOIDMsgLifeTimeMap.end())
									{
								
										//NOT FOUND
										pthread_mutex_unlock(&UOIDMsgLifeTimeMapMutex);
										pthread_mutex_lock(&tempfileindexlock);
										//tempFileIndex--;
										pthread_mutex_unlock(&tempfileindexlock);
										for(int i=0;i<numberOfSegments-1;i++)
											{
												
												if (remainingDataToBeRead > MAXFILEBUF)
												{
													bytesToBeRead = MAXFILEBUF;
													remainingDataToBeRead = remainingDataToBeRead - MAXFILEBUF;
												}
												else
													bytesToBeRead = remainingDataToBeRead;

												memset(&readBuf[0],0x00,MAXFILEBUF);
												int retdata=(int)recv(socketDesc,&readBuf,bytesToBeRead,0);
												if(retdata<0)
												{
												}
											}
										continue;
										//printf("EVENT DISPATCHER: STATUS RESPONSE. THERE HAS NOT BEEN ANY STATUS REQ FOR THIS UOID.\n\n");
										
									}
									else
									{
													msgLifeTimeClass tmp=(*uoidIterator).second;
													fwdToSocket=tmp.sockOfMsgReciept;
													pthread_mutex_unlock(&UOIDMsgLifeTimeMapMutex);
													//printf("ReadBuf54 is %x and Metabuf54 is %x\n",metaDataBuff[55],readBuf[59]);
													//printf("METABUF is %s\n",metaDataBuff);
													FILE *tempFData = fopen(tempDataFile, "w");
													FILE *tempFMeta = fopen(tempMetaFile, "w");
													int r = fwrite(metaDataBuff,1,metalength,tempFMeta);
													
													if (r == -1)
													{
														 //printf("Read thread: Error writing MEtafile\n");
													}

													//write the remainig data to datafile.
													r = fwrite(readBuf+24+metalength, 1,(bytesToBeRead) -(4+metalength),tempFData);
													if (r == -1)
													{
														 //printf("Read thread: Error writing Datafile-1\n");
													}

											
											
											//bool firstPacket=false;
											//printf("Number of segments:%d\n",numberOfSegments);
											for(int i=0;i<numberOfSegments-1;i++)
											{
												
												if (remainingDataToBeRead > MAXFILEBUF)
												{
													bytesToBeRead = MAXFILEBUF;
													remainingDataToBeRead = remainingDataToBeRead - MAXFILEBUF;
												}
												else
													bytesToBeRead = remainingDataToBeRead;

												memset(&readBuf[0],0x00,MAXFILEBUF);
												int retdata=(int)recv(socketDesc,&readBuf,bytesToBeRead,0);
												if(retdata<0)
												{
												}
											//	printf("Recv data is: %d\n%s\n\n\n\n",retdata,readBuf);
											//	printf("MetaLength is %02X%02X%02X%02X\n",readBuf[0],readBuf[1],readBuf[2],readBuf[3]);
												/*if(!firstPacket)
												{
													int metalength;
													memcpy(&metalength, readBuf,4);
													memcpy(&metaDataBuff[0],&readBuf[4],metalength);
													
													
													printf("Read threaad Metadata length : %d\n", metalength);
													//printf("ReadBuf54 is %x and Metabuf54 is %x\n",metaDataBuff[55],readBuf[59]);
													printf("METABUF is %s\n",metaDataBuff);
													int r = fwrite(readBuf+4,1,metalength,tempFMeta);
													
													if (r == -1)
													{
														 printf("Read thread: Error writing MEtafile\n");
													}

													//write the remainig data to datafile.
													r = fwrite(readBuf+4+metalength, 1,(bytesToBeRead) -(4+metalength),tempFData);
													if (r == -1)
													{
														 printf("Read thread: Error writing Datafile-1\n");
													}
													firstPacket=true;
												}
												else
												{*/
													int r = fwrite(readBuf, 1,(bytesToBeRead),tempFData);
													if (r == -1)
													{
														 //printf("Read thread: Error writing Datafile-1\n");
													}
												
												}
												
							
							fclose(tempFData);
							fclose(tempFMeta);	
						}
						} // Else of Maxbuf < datalength over
						/*
						while(1)
						{
							int retdata=(int)recv(socketDesc,&readBuf,readMsgHeader.msgDataLength,0);
							printf("%s\n",readMsgHeader.msgDataLength);
							//fwrite(readBuf, 1, readMsgHeader.msgDataLength, numDataFile);	
						}
						continue;
						*/
						

						//fclose(tempFData);
						//fclose(tempFMeta);	

						/* Logging message
								check for store probability to store the file into the node.
								float storecoinflip = drand48();
								if (storecoinflip <= StoreProb)
								{
									//rename the file
									//update the bit vector list
									//Update the sha1 structure list.
									//update the filenamelist
								}

							if (readMsgHeader.ttlInHeader > 0)
							then
								Iterate over the connectedNeighbourList
								for each neighbour, check if the coin flip probability is less than neighbour probability
									float coinflip = drand48();
									if (coinflip > NeighborStoreProb)
									{
										continue; //we do not flood this message.
									}
								flood message to all the nodes
								create itemQueue message
								fill the packet header
								fill the packet data(that is file name)
								push into write queue
							else
								do nothing to the packet
							
							
						*/
						//check for store probability to store the file into the node.

						
							size_t len=strlen((const char*)metaDataBuff);
							if(len<0)
							{
							}
							//printf("READ THREAD: Metadata:%s\n length is %d\n",(const char*)metaDataBuff,len);
							
							//printf("MetaLength is %X%X%X%X\n",metaDataBuff[0],metaDataBuff[1],metaDataBuff[2],metaDataBuff[3]);
							char *ptrTag[10];
							int tagId=0;
							char *ptrTagValue[10];
							int tagValueId=0;

							for (int i = 0; i<7 ; i++)
							{
								if (i == 0)
								{
									ptrTag[tagId] = strtok((char*)metaDataBuff, "\n");
									
									//printf("MetaTag-%d : [%s]\n", tagId, ptrTag[tagId]);
									tagId++;
								}
								else
								{
									ptrTag[tagId] = strtok((char*)NULL, "=");
									
									//printf("MetaTag-%d : [%s]\n", tagId, ptrTag[tagId]);
									tagId++;
									ptrTagValue[tagValueId] = strtok((char*)NULL, "\n");
									
									//printf("MetaTagValue-%d : [%s]\n", tagValueId, ptrTagValue[tagValueId]);
									tagValueId++;
								}
							}

					//	printf("The fwdSocket is %d\n",fwdToSocket);
						if(fwdToSocket == -1)  // Packet is for me. I was initiator
						{
							
							pthread_mutex_lock(&cntrlCFlagMutex);
							if(!cntrlCFlag)
							{
							if(!getFileNameSpcified)
							{
								memset(&getFileName[0],'\0',512);
								memcpy(&getFileName[0], ptrTagValue[0],256);
							}
							bool pathValid=false;
							struct stat s;
							if(stat(getFileName,&s) == -1){
								//printf("Invalid Path name\n");
								pathValid=false;
							}
							if (S_ISREG(s.st_mode))
							{
							  pathValid=true;
							}
							bool conformation=false;
							if(pathValid)
							{
								char overwrite[5];
								printf("File already exist. Do you want to overwrite(y/Y for YES. Anything else for NO)");
								scanf("%s",overwrite);
								printf("\n");

								if (  !(overwrite[0] == 'y') || !(overwrite[0] == 'Y'))
								{
									conformation=true;
						//			printf("Get command :File not replaced\n");
									//break;
								}
								else
								{
									
							
									
									
								
								}
								
							}
						//	printf("--------1-----\n");
							if (!conformation)
							{	

									struct stat statistics;
									int status;
									
									status = stat((char*)tempDataFile,&statistics);
									if(status<0)
									{
										//printf("File does not exist.\n");
									}
									unsigned int filesize = statistics.st_size;
									if(filesize)
									{}
							//		printf("Size of file %s is %u.\n",tempDataFile,filesize);
									FILE *fDataRead = fopen(tempDataFile,"r");
									FILE *wGetFile = fopen(getFileName,"w");

									int remainingDataToBeCopied = (int)atoi(ptrTagValue[1]);
							//		printf("File Size is %d\n",remainingDataToBeCopied);
									int numberOfSegments = ceil((double)remainingDataToBeCopied/MAXFILEBUF);	
									 char copyBuf[MAXFILEBUF];
									 memset(&copyBuf[0],'\0',MAXFILEBUF);
									for(int k=0;k<numberOfSegments;k++)
									{
										int bytestoread;
										if (remainingDataToBeCopied > MAXFILEBUF)
										{
											bytestoread = MAXFILEBUF;
											remainingDataToBeCopied = remainingDataToBeCopied - MAXFILEBUF;
										}
										else
											bytestoread = remainingDataToBeCopied;

										memset(&copyBuf[0],'\0',MAXFILEBUF);
										if (fread(copyBuf,1,bytestoread,fDataRead) < 0)
										{
											//printf("Error in reading data file\n");
										}
										fwrite(copyBuf, 1, bytestoread, wGetFile);	
									}
									fclose(fDataRead);
									fclose(wGetFile);



							}
							
							// Now check if duplicate file exist in /files dir.
							// If yes do nothing. Else write a copy in /files dir and insert new index data.
							pthread_mutex_lock(&indexMutex);

							list<indexFileMetaInfo>::iterator it;
							bool permFileAlreadyExist=false;
							for(it=indexFileMetaInfoList.begin();it!=indexFileMetaInfoList.end();it++)
							{
								if (!strcmp(ptrTagValue[0],(*it).originalFileName) && (!strcmp((char*)(*it).fileNonceValue,ptrTagValue[3])))
								{
												multimap<string,int>:: iterator it1;
												
												for(it1=indexSHA1Map.begin();it1!=indexSHA1Map.end();it1++)
												{		
													//it2 = indexSHA1Map.find(sha1);
													if(strcmp((const char*)(*it1).first.c_str(),ptrTagValue[2])==0 && ((*it1).second==(*it).numFileName) )
													{
														//	it1=indexSHA1Map.find(str1);
														permFileAlreadyExist=true;
														if((*it).isInCache)
														{
															(*it).isInCache=false;
															remainingCacheSizeInBytes+=(*it).filesize;
														}

														break;
													}
												}
												if(permFileAlreadyExist)
												{

													break;
												}
												
						
								}
							}
							
						//	cout<<"permFileAlreadyExist is "<<permFileAlreadyExist<<endl;
							if(!permFileAlreadyExist)
							{
								char appendDFileName[256];
									char appendMFileName[256];
									memset(&appendMFileName[0],'\0',256);
									memset(&appendDFileName[0],'\0',256);

									numfileId=numFileNameCounter++;

									sprintf(appendDFileName, "/%d.data", numfileId);
									sprintf(appendMFileName, "/%d.meta", numfileId);
									
									char newNumDataFile[256];
									char newNumMetaFile[256];
									memset(newNumDataFile, '\0', 256);
									memset(newNumMetaFile, '\0', 256);
									
									memcpy(newNumDataFile,homeDir,strlen(homeDir));
									strcat(newNumDataFile,"/files");
									
									//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
									mkdir(newNumDataFile,S_IRWXU | S_IRWXG | S_IRWXO);
									strcat(newNumDataFile,appendDFileName); //Change it to variable numebr file generated in indexing above
									

									memcpy(newNumMetaFile,homeDir,strlen(homeDir));
									strcat(newNumMetaFile,"/files");
									mkdir(newNumMetaFile,S_IRWXU | S_IRWXG | S_IRWXO);
									//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
									
									strcat(newNumMetaFile,appendMFileName); //Change it to variable numebr file generated in indexing above

									
					//				printf("READ THREAD RENAME: Data File Path is: %s\n",newNumDataFile);
					//				printf("READ THREAD RENAME: Meta File Path is: %s\n",newNumMetaFile);
									

									int res = rename(tempDataFile, newNumDataFile);
										if (res < 0)
										{
										
												//printf("Read Thread: Rename of Datafile unsuccessful\n");
											
										}
										
										res = rename(tempMetaFile, newNumMetaFile);
										if (res < 0)
										{
												//printf("Read Thread: Rename of Metafile unsuccessful\n");
										
										}
									
											
									// Update all index structures.	
									

									
									//update the bit vector list
									//Update the sha1 structure list.
									//update the filenamelist

									   char fileID[20];
									  unsigned char *buff1;
									char* msg = (char*)"file";

									//printf("NodeID is %s\n",nodeInstanceId);
									
									buff1=GetUOID((char *)nodeInstanceId,msg,buf, sizeof(buf));
									memcpy(&fileID[0],&buf[0],20);
									
									// populate bitvector index list
									bitVectorIndexItem indexBVItem;
									memcpy(&indexBVItem.indexBitVector[0],& ptrTagValue[5][0],256);
									indexBVItem.numFileName=numfileId;
									indexBitVectoreList.push_back(indexBVItem);
									
									//populate SHA1 vs numeric name map
									indexSHA1Map.insert(pair<string,int>(string( ptrTagValue[2]),numfileId));
									// populate the numeric name vs fildId map
									numToFileIdMap.insert(pair<int,string>(numfileId,string(fileID)));


									// populate the meta info list.

									indexFileMetaInfo fileMetaInfo;
									memset(&fileMetaInfo.originalFileName[0],'\0',256);
									memcpy(&fileMetaInfo.originalFileName[0],& ptrTagValue[0][0],strlen( ptrTagValue[0]));
									fileMetaInfo.numFileName=numfileId;
									
									memcpy(&fileMetaInfo.fileID[0],&fileID[0],20);
									int newfilesize = (int)atoi(ptrTagValue[1]);
									fileMetaInfo.filesize=newfilesize;
									fileMetaInfo.isInCache=false;
									//remainingCacheSizeInBytes=remainingCacheSizeInBytes-fileMetaInfo.filesize;
									char randFilePassword[21];
									memset(&randFilePassword[0],'\0',21);
									memcpy(&fileMetaInfo.filePassword[0],&randFilePassword[0],20);
									memcpy(&fileMetaInfo.fileNonceValue[0],& ptrTagValue[3][0],40);
									
									indexFileMetaInfoList.push_back(fileMetaInfo);

							//		printf("--------1-----\n");



							}


							pthread_mutex_unlock(&indexMutex);
						//	printf("--------2-----\n");
							}
							pthread_mutex_unlock(&cntrlCFlagMutex);
									
									

							//==============

						}
						else					// Packet not for me. Forward it to the fwdToScoket node.
						{
							
							float cachecoinflip = drand48();
							
							if (cachecoinflip <= cacheProb)
							{
								int newFileSize = (int)atoi(ptrTagValue[1]);
								if(newFileSize < cacheSizeInBytes)
								{
									//check for file duplication .
											pthread_mutex_lock(&indexMutex);
											list<indexFileMetaInfo>::iterator it;
											bool permFileAlreadyExist=false;
											for(it=indexFileMetaInfoList.begin();it!=indexFileMetaInfoList.end();it++)
											{
												if (!strcmp(ptrTagValue[0],(*it).originalFileName) && (!strcmp((char*)(*it).fileNonceValue,ptrTagValue[3])))
												{
																multimap<string,int>:: iterator it1;
												
																for(it1=indexSHA1Map.begin();it1!=indexSHA1Map.end();it1++)
																{		
																	//it2 = indexSHA1Map.find(sha1);
																	if(strcmp((const char*)(*it1).first.c_str(),ptrTagValue[2])==0 && ((*it1).second==(*it).numFileName) )
																	{
																		//	it1=indexSHA1Map.find(str1);
																		permFileAlreadyExist=true;
																		if((*it).isInCache)
																		{
																			(*it).isInCache=false;
																			remainingCacheSizeInBytes+=(*it).filesize;
																		}

																		break;
																	}
																}
																if(permFileAlreadyExist)
																{

																	break;
																}
												
												}
											}
										
									// Implemet LRU to free up space for caching.
									if(!permFileAlreadyExist)
									{
									
									if(newFileSize > remainingCacheSizeInBytes)
									{
										// Remove the files from the cache untill the required space gets generated.
										list<indexFileMetaInfo>::iterator it;
										it=indexFileMetaInfoList.begin();
										while(newFileSize > remainingCacheSizeInBytes)
										{
											indexFileMetaInfo toBeDeleted = (*it);
											if(toBeDeleted.isInCache)
											{
												int numberIdOfFileToBeRemoved = toBeDeleted.numFileName;
												//restore cache space.
												remainingCacheSizeInBytes+=toBeDeleted.filesize;

												// Remove the SHA1Map entry.
												map<string,int>:: iterator it1;
												for(it1=indexSHA1Map.begin();it1!=indexSHA1Map.end();it1++)
												{
													if((*it1).second == numberIdOfFileToBeRemoved)
													{
														indexSHA1Map.erase(it1);
														break;
													}
												}
												// Remove entry from bitvector map
												list<bitVectorIndexItem>:: iterator it2;
												for(it2=indexBitVectoreList.begin();it2!=indexBitVectoreList.end();it2++)
												{
													bitVectorIndexItem tempDelete = (*it2);
													if(tempDelete.numFileName == numberIdOfFileToBeRemoved)
													{
														indexBitVectoreList.erase(it2);
														break;
													}
												}
												//remove the file ID map entry.
												map<int,string>:: iterator it3;
												for(it3=numToFileIdMap.begin();it3!=numToFileIdMap.end();it3++)
												{
													if((*it3).first == numberIdOfFileToBeRemoved)
													{
														numToFileIdMap.erase(it3);
														break;
													}
												}

												//delete the corrosponding files from the node.

												char appendDFileName[256];
												char appendMFileName[256];
												memset(&appendMFileName[0],'\0',256);
												memset(&appendDFileName[0],'\0',256);

												//numfileId=numFileNameCounter++;

												sprintf(appendDFileName, "/%d.data", numberIdOfFileToBeRemoved);
												sprintf(appendMFileName, "/%d.meta", numberIdOfFileToBeRemoved);
												
												char newNumDataFile[256];
												char newNumMetaFile[256];
												memset(newNumDataFile, '\0', 256);
												memset(newNumMetaFile, '\0', 256);
												
												memcpy(newNumDataFile,homeDir,strlen(homeDir));
												strcat(newNumDataFile,"/files");
												
												//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
												//mkdir(newNumDataFile,S_IRWXU | S_IRWXG | S_IRWXO);
												strcat(newNumDataFile,appendDFileName); //Change it to variable numebr file generated in indexing above
												

												memcpy(newNumMetaFile,homeDir,strlen(homeDir));
												strcat(newNumMetaFile,"/files");
												//mkdir(newNumMetaFile,S_IRWXU | S_IRWXG | S_IRWXO);
												//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
												
												strcat(newNumMetaFile,appendMFileName); //Change it to variable numebr file generated in indexing above
												remove(newNumDataFile);
												remove(newNumMetaFile);


												indexFileMetaInfoList.erase(it);
												

											}
											else
											{
												it++;
											}
										}
									}

								//Rename the temp file.	
								isStored=true;
									char appendDFileName[256];
									char appendMFileName[256];
									memset(&appendMFileName[0],'\0',256);
									memset(&appendDFileName[0],'\0',256);

									numfileId=numFileNameCounter++;

									sprintf(appendDFileName, "/%d.data", numfileId);
									sprintf(appendMFileName, "/%d.meta", numfileId);
									
									char newNumDataFile[256];
									char newNumMetaFile[256];
									memset(newNumDataFile, '\0', 256);
									memset(newNumMetaFile, '\0', 256);
									
									memcpy(newNumDataFile,homeDir,strlen(homeDir));
									strcat(newNumDataFile,"/files");
									
									//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
									mkdir(newNumDataFile,S_IRWXU | S_IRWXG | S_IRWXO);
									strcat(newNumDataFile,appendDFileName); //Change it to variable numebr file generated in indexing above
									

									memcpy(newNumMetaFile,homeDir,strlen(homeDir));
									strcat(newNumMetaFile,"/files");
									mkdir(newNumMetaFile,S_IRWXU | S_IRWXG | S_IRWXO);
									//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
									
									strcat(newNumMetaFile,appendMFileName); //Change it to variable numebr file generated in indexing above

									
							//		printf("READ THREAD RENAME: Data File Path is: %s\n",newNumDataFile);
							//		printf("READ THREAD RENAME: Meta File Path is: %s\n",newNumMetaFile);
									

									int res = rename(tempDataFile, newNumDataFile);
										if (res < 0)
										{
										
												//printf("Read Thread: Rename of Datafile unsuccessful\n");
											
										}
										
										res = rename(tempMetaFile, newNumMetaFile);
										if (res < 0)
										{
												//printf("Read Thread: Rename of Metafile unsuccessful\n");
										
										}
										
																		

									// Update all index structures.	
									

									
									//update the bit vector list
									//Update the sha1 structure list.
									//update the filenamelist

									   char fileID[20];
									  unsigned char *buff1;
									char* msg = (char*)"file";

									//printf("NodeID is %s\n",nodeInstanceId);
									
									buff1=GetUOID((char *)nodeInstanceId,msg,buf, sizeof(buf));
									memcpy(&fileID[0],&buf[0],20);
									
									// populate bitvector index list
									bitVectorIndexItem indexBVItem;
									memcpy(&indexBVItem.indexBitVector[0],& ptrTagValue[5][0],256);
									indexBVItem.numFileName=numfileId;
									indexBitVectoreList.push_back(indexBVItem);
									
									//populate SHA1 vs numeric name map
									indexSHA1Map.insert(pair<string,int>(string( ptrTagValue[2]),numfileId));
									// populate the numeric name vs fildId map
									numToFileIdMap.insert(pair<int,string>(numfileId,string(fileID)));


									// populate the meta info list.

									indexFileMetaInfo fileMetaInfo;
									memset(&fileMetaInfo.originalFileName[0],'\0',256);
									memcpy(&fileMetaInfo.originalFileName[0],& ptrTagValue[0][0],strlen( ptrTagValue[0]));
									fileMetaInfo.numFileName=numfileId;
									
									memcpy(&fileMetaInfo.fileID[0],&fileID[0],20);
									int newFileSize = (int)atoi(ptrTagValue[1]);
									fileMetaInfo.filesize=newFileSize;
									fileMetaInfo.isInCache=true;
									remainingCacheSizeInBytes=remainingCacheSizeInBytes-fileMetaInfo.filesize;
									char randFilePassword[21];
									memset(&randFilePassword[0],'\0',21);
									memcpy(&fileMetaInfo.filePassword[0],&randFilePassword[0],20);
									memcpy(&fileMetaInfo.fileNonceValue[0],& ptrTagValue[3][0],40);
									
									indexFileMetaInfoList.push_back(fileMetaInfo);

									
									}
									pthread_mutex_unlock(&indexMutex);
									



								}

							}
							//fORWARD TO THE OTHER NODE
											
											queueItem msgToInsertInWrite;
											msgToInsertInWrite.sockfd=fwdToSocket;
											msgToInsertInWrite.msgHeader=readMsgHeader;
											memcpy(&msgToInsertInWrite.dataBuf[0],&dataUOID[0],20);

											if(isStored)
											{
												msgToInsertInWrite.dataBuf[20] = (char)numfileId;
												msgToInsertInWrite.dataBuf[21] = (char)' ';
												msgToInsertInWrite.dataBuf[22] = (char)'0';
											}
											else
											{	
												msgToInsertInWrite.dataBuf[20] = (char)temptempFileId;
												msgToInsertInWrite.dataBuf[21] = (char)' ';
												msgToInsertInWrite.dataBuf[22] = (char)'1';
											}

										pthread_mutex_lock(&sockIndexMapMutex);
												int index=sockFDToQIndexMap[fwdToSocket];
													pthread_mutex_lock(&wrtieQMutex[index]);
													//	printf("DISPATCHER: Will push %s data in queue.\n\n",msgToBePushed.dataBuf);
														wrtieThreadQueue[index].push_back(msgToInsertInWrite);
														//printf("EVENT DISPATCHER: JOIN MSG: Msg pushed to writeQueue of %d\n",index);
														pthread_cond_broadcast(&wrtieQCV[index]);

													pthread_mutex_unlock(&wrtieQMutex[index]);								
												pthread_mutex_unlock(&sockIndexMapMutex);
											
											



									
								pthread_mutex_lock(&connectedNodeListMutex);
									uint16_t portTemp=0;
									char *tempHost=(char*)malloc(512);

								map<string,int>::iterator it;
								for(it=connectedNodeList.begin() ; it != connectedNodeList.end(); it++ )
								{
									if((*it).second==fwdToSocket)
									{
												char* str1 = (char*) malloc(512); 
												memset(&str1[0],'\0',512);
												memcpy(&str1[0],&(((*it).first).c_str()[0]),19);

												char *str=(char*)malloc(512);
												memset(str,'\0',512);
												memcpy(&str[0],&str1[0],strlen(str1));
												//printf("String from list is %s\n",str);
												
												tempHost=strtok(str,"_");
												//printf("TempHost is %s and length is %d\n",tempHost,(int)strlen(tempHost));
												char *tempPort=strtok(NULL,"_");
												//printf("TempPort is %s and length is %d\n",tempPort,(int)strlen(tempPort));
												
												portTemp=atoi(tempPort);
												break;
									}
								
								}
							pthread_mutex_unlock(&connectedNodeListMutex);

									pthread_mutex_lock(&logFileMutex);

										gettimeofday(&tv, NULL); 
										int sec = tv.tv_sec ;
										int msec = tv.tv_usec/1000;
										char *time = (char *)malloc(14);
										memset(time,0,14);
										sprintf(time,"%10ld.%03d",(long)sec,msec);
										time[strlen(time)]='\0';

										



										fprintf(logFilePtr, "f  %s %s:%hu GTRS %d 0x%02x %x%x%x%x %x%x%x%x\n",time,
											tempHost,
											portTemp,
											(msgToInsertInWrite.msgHeader.msgDataLength+27),
											(unsigned char)msgToInsertInWrite.msgHeader.ttlInHeader,
											(unsigned char)msgToInsertInWrite.msgHeader.UOID[16],
											(unsigned char)msgToInsertInWrite.msgHeader.UOID[17],
											(unsigned char)msgToInsertInWrite.msgHeader.UOID[18],
											(unsigned char)msgToInsertInWrite.msgHeader.UOID[19],
											(unsigned char)msgToInsertInWrite.dataBuf[16],
											(unsigned char)msgToInsertInWrite.dataBuf[17],
											(unsigned char)msgToInsertInWrite.dataBuf[18],
											(unsigned char)msgToInsertInWrite.dataBuf[19]);
											//helloRecvData.HostPort,helloRecvData.Hostname);
										pthread_mutex_unlock(&logFileMutex);








						}
						remove(tempDataFile);
						remove(tempMetaFile);
				//	printf("Outside fwdsocket check.\n");
				}
			}
			else if(readMsgHeader.messageType==0xCC)
			{
	//			printf("---------Read Thread: header is :\n");
	/*			printf("r STRS %d 0x%02x %x%x%x%x  on socket %d\n",
								(readMsgHeader.msgDataLength),
								(unsigned char)readMsgHeader.ttlInHeader,
								(unsigned char)readMsgHeader.UOID[16],
								(unsigned char)readMsgHeader.UOID[17],
								(unsigned char)readMsgHeader.UOID[18],
								(unsigned char)readMsgHeader.UOID[19],socketDesc);
*/
				//decrement ttl here which is used for flooding below.
				if((readMsgHeader.ttlInHeader-1)<ttl)
				{
					readMsgHeader.ttlInHeader=readMsgHeader.ttlInHeader-1;
				}
				else
				{
					readMsgHeader.ttlInHeader=ttl;	
				}
				
				
				unsigned char readBuf[MAXFILEBUF];
				memset(&readBuf[0],0x00,MAXFILEBUF);
				
				unsigned char metaDataBuff[MAXFILEBUF];
				memset(&readBuf[0],0x00,MAXFILEBUF);
				map<string,msgLifeTimeClass>::iterator uoidIterator;
				string str ((const char*)readMsgHeader.UOID,20);

				pthread_mutex_lock(&UOIDMsgLifeTimeMapMutex);
				uoidIterator=UOIDMsgLifeTimeMap.find(str);

				if(uoidIterator == UOIDMsgLifeTimeMap.end())
				{
						unsigned char uoidToInsertInMap[20];
						memcpy(&uoidToInsertInMap[0],readMsgHeader.UOID,20);
						string uoid((const char*)uoidToInsertInMap,20);
						msgLifeTimeClass newEntry(socketDesc,msgLifeTime);
						//newEntry.sockOfMsgReciept=itemFromQueue.sockfd;
						//newEntry.msgLifeTimeValue=msgLifeTime;
						UOIDMsgLifeTimeMap.insert(pair<string,msgLifeTimeClass>(uoid,newEntry));

						pthread_mutex_unlock(&UOIDMsgLifeTimeMapMutex);


						char tempDataFile[256];
						char tempMetaFile[256];
						memset(tempDataFile, '\0', 256);
						memset(tempMetaFile, '\0', 256);
						pthread_mutex_lock(&tempfileindexlock);
						sprintf(tempDataFile, "%s/%d.data", homeDir, tempFileIndex);
						sprintf(tempMetaFile, "%s/%d.meta", homeDir, tempFileIndex);
						int temptempFileId=tempFileIndex++;
						pthread_mutex_unlock(&tempfileindexlock);

						FILE *tempFData = fopen(tempDataFile, "w");
						FILE *tempFMeta = fopen(tempMetaFile, "w");
			//			printf("Recieve msg Header data length: %d\n",readMsgHeader.msgDataLength);
						if(readMsgHeader.msgDataLength<=MAXFILEBUF)
						{
							int retdata=(int)recv(socketDesc,&readBuf,readMsgHeader.msgDataLength,0);
							if(retdata<0)
							{
								
							}



						pthread_mutex_lock(&connectedNodeListMutex);
									uint16_t portTemp=0;
									char *tempHost=(char*)malloc(512);

								map<string,int>::iterator it;
								for(it=connectedNodeList.begin() ; it != connectedNodeList.end(); it++ )
								{
									if((*it).second==socketDesc)
									{
												char* str1 = (char*) malloc(512); 
												memset(&str1[0],'\0',512);
												memcpy(&str1[0],&(((*it).first).c_str()[0]),19);

												char *str=(char*)malloc(512);
												memset(str,'\0',512);
												memcpy(&str[0],&str1[0],strlen(str1));
												//printf("String from list is %s\n",str);
												
												tempHost=strtok(str,"_");
												//printf("TempHost is %s and length is %d\n",tempHost,(int)strlen(tempHost));
												char *tempPort=strtok(NULL,"_");
												//printf("TempPort is %s and length is %d\n",tempPort,(int)strlen(tempPort));
												
												portTemp=atoi(tempPort);
												break;
									}
								
								}
				pthread_mutex_unlock(&connectedNodeListMutex);

									pthread_mutex_lock(&logFileMutex);

										gettimeofday(&tv, NULL); 
										int sec = tv.tv_sec ;
										int msec = tv.tv_usec/1000;
										char *time = (char *)malloc(14);
										memset(time,0,14);
										sprintf(time,"%10ld.%03d",(long)sec,msec);
										time[strlen(time)]='\0';

										



										fprintf(logFilePtr, "r  %s %s:%hu STOR %d 0x%02x %x%x%x%x\n",time,
											tempHost,
											portTemp,
											(readMsgHeader.msgDataLength+27),
											(unsigned char)readMsgHeader.ttlInHeader,
											(unsigned char)readMsgHeader.UOID[16],
											(unsigned char)readMsgHeader.UOID[17],
											(unsigned char)readMsgHeader.UOID[18],
											(unsigned char)readMsgHeader.UOID[19]);
											//helloRecvData.HostPort,helloRecvData.Hostname);
										pthread_mutex_unlock(&logFileMutex);








			//				printf("MetaLength is %X%X%X%X\n",readBuf[0],readBuf[1],readBuf[2],readBuf[3]);
			//				printf("%s\n\n\n\n",readBuf);
							
							int metalength;
							memcpy(&metalength, readBuf,4);
							//localmetalength = metalength;
							
			//				printf("1 Read threaad Metadata length : %d\n", metalength);
							memcpy(&metaDataBuff[0],&readBuf[4],metalength);
							
							int r = fwrite(readBuf+4,1,metalength,tempFMeta);
							if (r == -1)
							{
								 //printf("Read thread: Error writing MEtafile\n");
							}

							//write the remainig data to datafile.
							r = fwrite(readBuf+4+metalength, 1,(readMsgHeader.msgDataLength) -(4+metalength),tempFData);
							if (r == -1)
							{
								 //printf("Read thread: Error writing Datafile-1\n");
							}
							//fclose(tempFData);
							//fclose(tempFMeta);						
						}
						else
						{	

			
						
							int numberOfSegments = ceil((double)(readMsgHeader.msgDataLength)/MAXFILEBUF);
							
							int remainingDataToBeRead = readMsgHeader.msgDataLength;
							bool firstPacket=false;
							//printf("Number of segments:%d\n",numberOfSegments);
							for(int i=0;i<numberOfSegments;i++)
							{
								int bytesToBeRead;
								if (remainingDataToBeRead > MAXFILEBUF)
								{
									bytesToBeRead = MAXFILEBUF;
									remainingDataToBeRead = remainingDataToBeRead - MAXFILEBUF;
								}
								else
									bytesToBeRead = remainingDataToBeRead;

								memset(&readBuf[0],0x00,MAXFILEBUF);
								int retdata=(int)recv(socketDesc,&readBuf,bytesToBeRead,0);
								if(retdata<0)
								{

								}
							//	printf("Recv data is: %d\n%s\n\n\n\n",retdata,readBuf);
							//	printf("MetaLength is %02X%02X%02X%02X\n",readBuf[0],readBuf[1],readBuf[2],readBuf[3]);
								if(!firstPacket)
								{
									int metalength;
									memcpy(&metalength, readBuf,4);
									memcpy(&metaDataBuff[0],&readBuf[4],metalength);
									




						pthread_mutex_lock(&connectedNodeListMutex);
									uint16_t portTemp=0;
									char *tempHost=(char*)malloc(512);

								map<string,int>::iterator it;
								for(it=connectedNodeList.begin() ; it != connectedNodeList.end(); it++ )
								{
									if((*it).second==socketDesc)
									{
												char* str1 = (char*) malloc(512); 
												memset(&str1[0],'\0',512);
												memcpy(&str1[0],&(((*it).first).c_str()[0]),19);

												char *str=(char*)malloc(512);
												memset(str,'\0',512);
												memcpy(&str[0],&str1[0],strlen(str1));
												//printf("String from list is %s\n",str);
												
												tempHost=strtok(str,"_");
												//printf("TempHost is %s and length is %d\n",tempHost,(int)strlen(tempHost));
												char *tempPort=strtok(NULL,"_");
												//printf("TempPort is %s and length is %d\n",tempPort,(int)strlen(tempPort));
												
												portTemp=atoi(tempPort);
												break;
									}
								
								}
				pthread_mutex_unlock(&connectedNodeListMutex);

									pthread_mutex_lock(&logFileMutex);

										gettimeofday(&tv, NULL); 
										int sec = tv.tv_sec ;
										int msec = tv.tv_usec/1000;
										char *time = (char *)malloc(14);
										memset(time,0,14);
										sprintf(time,"%10ld.%03d",(long)sec,msec);
										time[strlen(time)]='\0';

										



										fprintf(logFilePtr, "r  %s %s:%hu STOR %d 0x%02x %x%x%x%x\n",time,
											tempHost,
											portTemp,
											(readMsgHeader.msgDataLength+27),
											(unsigned char)readMsgHeader.ttlInHeader,
											(unsigned char)readMsgHeader.UOID[16],
											(unsigned char)readMsgHeader.UOID[17],
											(unsigned char)readMsgHeader.UOID[18],
											(unsigned char)readMsgHeader.UOID[19]);
											//helloRecvData.HostPort,helloRecvData.Hostname);
										pthread_mutex_unlock(&logFileMutex);







									
									//printf("Read threaad Metadata length : %d\n", metalength);
									//printf("ReadBuf54 is %x and Metabuf54 is %x\n",metaDataBuff[55],readBuf[59]);
									//printf("METABUF is %s\n",metaDataBuff);
									int r = fwrite(readBuf+4,1,metalength,tempFMeta);
									
									if (r == -1)
									{
										 //printf("Read thread: Error writing MEtafile\n");
									}

									//write the remainig data to datafile.
									r = fwrite(readBuf+4+metalength, 1,(bytesToBeRead) -(4+metalength),tempFData);
									if (r == -1)
									{
										 //printf("Read thread: Error writing Datafile-1\n");
									}
									firstPacket=true;
								}
								else
								{
									int r = fwrite(readBuf, 1,(bytesToBeRead),tempFData);
									if (r == -1)
									{
										 //printf("Read thread: Error writing Datafile-1\n");
									}
								
								}
								
							}
							//fclose(tempFData);
							//fclose(tempFMeta);	

						/*
						while(1)
						{
							int retdata=(int)recv(socketDesc,&readBuf,readMsgHeader.msgDataLength,0);
							printf("%s\n",readMsgHeader.msgDataLength);
							//fwrite(readBuf, 1, readMsgHeader.msgDataLength, numDataFile);	
						}
						continue;
						*/
						}

						fclose(tempFData);
						fclose(tempFMeta);	

						/* Logging message
								check for store probability to store the file into the node.
								float storecoinflip = drand48();
								if (storecoinflip <= StoreProb)
								{
									//rename the file
									//update the bit vector list
									//Update the sha1 structure list.
									//update the filenamelist
								}

							if (readMsgHeader.ttlInHeader > 0)
							then
								Iterate over the connectedNeighbourList
								for each neighbour, check if the coin flip probability is less than neighbour probability
									float coinflip = drand48();
									if (coinflip > NeighborStoreProb)
									{
										continue; //we do not flood this message.
									}
								flood message to all the nodes
								create itemQueue message
								fill the packet header
								fill the packet data(that is file name)
								push into write queue
							else
								do nothing to the packet
							
							
						*/
						//check for store probability to store the file into the node.
						
						char *ptrTag[10];
							int tagId=0;
							char *ptrTagValue[10];
							int tagValueId=0;

							for (int i = 0; i<7 ; i++)
							{
								if (i == 0)
								{
									ptrTag[tagId] = strtok((char*)metaDataBuff, "\n");
									
				//					printf("MetaTag-%d : [%s]\n", tagId, ptrTag[tagId]);
									tagId++;
								}
								else
								{
									ptrTag[tagId] = strtok((char*)NULL, "=");
									
				//					printf("MetaTag-%d : [%s]\n", tagId, ptrTag[tagId]);
									tagId++;
									ptrTagValue[tagValueId] = strtok((char*)NULL, "\n");
									
				//					printf("MetaTagValue-%d : [%s]\n", tagValueId, ptrTagValue[tagValueId]);
									tagValueId++;
								}
							}
							
						char sha1buf[MAXFILEBUF+1];
	
						SHA_CTX c;
						SHA1_Init(&c);

						FILE *tdf = fopen(tempDataFile, "r");
						int fsize = (int)atoi(ptrTagValue[1]);
						int numberOfSegment = ceil((double)fsize/MAXFILEBUF);	
						//printf("Number of Segments is %d\n",numberOfSegment);
						int dataleft=fsize;
						for(int k=0;k<numberOfSegment;k++)
						{
							int bytestoread;
							if (dataleft > MAXFILEBUF)
							{
								bytestoread = MAXFILEBUF;
								dataleft = dataleft - MAXFILEBUF;
							}
							else
								bytestoread = dataleft;

							memset(sha1buf,'\0', MAXFILEBUF+1);
							if (fread(sha1buf,1,bytestoread,tdf) < 0)
							{
								//printf("Error in reading data temp file\n");
							}
							SHA1_Update(&c,(void *)sha1buf,bytestoread);
						}

						fclose(tdf);
						unsigned char computedSHA1[20];
						SHA1_Final(computedSHA1,&c);

						char formattedFileSha1[41];
						memset(&formattedFileSha1[0],'\0',41);
						for (int i =0 ;i< 20 ;i++)
						{
							unsigned char change[3] = {0};
							sprintf((char*)change, "%2.2x", computedSHA1[i]);
							sprintf((char*)formattedFileSha1+2*i,"%s",change);
						}
						
						bool checksumCorrect=true;;
						if(!strncmp((const char*)computedSHA1,(const char*)ptrTagValue[2],40))
						{
							checksumCorrect=false;
						}



						if(!checksumCorrect)
						{
							remove(tempDataFile);
							remove(tempMetaFile);
							continue;
						}





						bool isStored = false;
						float storecoinflip = drand48();
						int numfileId;
						if (storecoinflip <= storeProb)
						{
							

							pthread_mutex_lock(&indexMutex);
							
							
					//		size_t len=strlen((const char*)metaDataBuff);
					//		printf("READ THREAD: Metadata:%s\n length is %d\n",(const char*)metaDataBuff,len);
							
							//printf("MetaLength is %X%X%X%X\n",metaDataBuff[0],metaDataBuff[1],metaDataBuff[2],metaDataBuff[3]);
						/*	char *ptrTag[10];
							int tagId=0;
							char *ptrTagValue[10];
							int tagValueId=0;

							for (int i = 0; i<7 ; i++)
							{
								if (i == 0)
								{
									ptrTag[tagId] = strtok((char*)metaDataBuff, "\n");
									
									printf("MetaTag-%d : [%s]\n", tagId, ptrTag[tagId]);
									tagId++;
								}
								else
								{
									ptrTag[tagId] = strtok((char*)NULL, "=");
									
							//		printf("MetaTag-%d : [%s]\n", tagId, ptrTag[tagId]);
									tagId++;
									ptrTagValue[tagValueId] = strtok((char*)NULL, "\n");
									
						//			printf("MetaTagValue-%d : [%s]\n", tagValueId, ptrTagValue[tagValueId]);
									tagValueId++;
								}
							}*/
							

							int newfilesize = (int)atoi(ptrTagValue[1]);
							// If cache size id not enough implement the LRU here..
							if(newfilesize <= cacheSizeInBytes)
							{
							
									isStored = true;
									//rename the file.
									if(newfilesize > remainingCacheSizeInBytes)
									{
										// Remove the files from the cache untill the required space gets generated.
										list<indexFileMetaInfo>::iterator it;
										it=indexFileMetaInfoList.begin();
										while(newfilesize > remainingCacheSizeInBytes)
										{
											indexFileMetaInfo toBeDeleted = (*it);
											if(toBeDeleted.isInCache)
											{
												int numberIdOfFileToBeRemoved = toBeDeleted.numFileName;
												//restore cache space.
												remainingCacheSizeInBytes+=toBeDeleted.filesize;

												// Remove the SHA1Map entry.
												map<string,int>:: iterator it1;
												for(it1=indexSHA1Map.begin();it1!=indexSHA1Map.end();it1++)
												{
													if((*it1).second == numberIdOfFileToBeRemoved)
													{
														indexSHA1Map.erase(it1);
														break;
													}
												}
												// Remove entry from bitvector map
												list<bitVectorIndexItem>:: iterator it2;
												for(it2=indexBitVectoreList.begin();it2!=indexBitVectoreList.end();it2++)
												{
													bitVectorIndexItem tempDelete = (*it2);
													if(tempDelete.numFileName == numberIdOfFileToBeRemoved)
													{
														indexBitVectoreList.erase(it2);
														break;
													}
												}
												//remove the file ID map entry.
												map<int,string>:: iterator it3;
												for(it3=numToFileIdMap.begin();it3!=numToFileIdMap.end();it3++)
												{
													if((*it3).first == numberIdOfFileToBeRemoved)
													{
														numToFileIdMap.erase(it3);
														break;
													}
												}

												//delete the corrosponding files from the node.

												char appendDFileName[256];
												char appendMFileName[256];
												memset(&appendMFileName[0],'\0',256);
												memset(&appendDFileName[0],'\0',256);

												//numfileId=numFileNameCounter++;

												sprintf(appendDFileName, "/%d.data", numberIdOfFileToBeRemoved);
												sprintf(appendMFileName, "/%d.meta", numberIdOfFileToBeRemoved);
												
												char newNumDataFile[256];
												char newNumMetaFile[256];
												memset(newNumDataFile, '\0', 256);
												memset(newNumMetaFile, '\0', 256);
												
												memcpy(newNumDataFile,homeDir,strlen(homeDir));
												strcat(newNumDataFile,"/files");
												
												//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
												//mkdir(newNumDataFile,S_IRWXU | S_IRWXG | S_IRWXO);
												strcat(newNumDataFile,appendDFileName); //Change it to variable numebr file generated in indexing above
												

												memcpy(newNumMetaFile,homeDir,strlen(homeDir));
												strcat(newNumMetaFile,"/files");
												//mkdir(newNumMetaFile,S_IRWXU | S_IRWXG | S_IRWXO);
												//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
												
												strcat(newNumMetaFile,appendMFileName); //Change it to variable numebr file generated in indexing above
												remove(newNumDataFile);
												remove(newNumMetaFile);


												indexFileMetaInfoList.erase(it);
												

											}
											else
											{
												it++;
											}
										}
									}
									
									
									
									char appendDFileName[256];
									char appendMFileName[256];
									memset(&appendMFileName[0],'\0',256);
									memset(&appendDFileName[0],'\0',256);

									numfileId=numFileNameCounter++;

									sprintf(appendDFileName, "/%d.data", numfileId);
									sprintf(appendMFileName, "/%d.meta", numfileId);
									
									char newNumDataFile[256];
									char newNumMetaFile[256];
									memset(newNumDataFile, '\0', 256);
									memset(newNumMetaFile, '\0', 256);
									
									memcpy(newNumDataFile,homeDir,strlen(homeDir));
									strcat(newNumDataFile,"/files");
									
									//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
									mkdir(newNumDataFile,S_IRWXU | S_IRWXG | S_IRWXO);
									strcat(newNumDataFile,appendDFileName); //Change it to variable numebr file generated in indexing above
									

									memcpy(newNumMetaFile,homeDir,strlen(homeDir));
									strcat(newNumMetaFile,"/files");
									mkdir(newNumMetaFile,S_IRWXU | S_IRWXG | S_IRWXO);
									//http://www.linuxquestions.org/questions/programming-9/mkdir-in-c-setting-wrong-permissions-613250/
									
									strcat(newNumMetaFile,appendMFileName); //Change it to variable numebr file generated in indexing above

									
							//		printf("READ THREAD RENAME: Data File Path is: %s\n",newNumDataFile);
							//		printf("READ THREAD RENAME: Meta File Path is: %s\n",newNumMetaFile);
									

									int res = rename(tempDataFile, newNumDataFile);
										if (res < 0)
										{
										
												//printf("Read Thread: Rename of Datafile unsuccessful\n");
											
										}
										
										res = rename(tempMetaFile, newNumMetaFile);
										if (res < 0)
										{
												//printf("Read Thread: Rename of Metafile unsuccessful\n");
										
										}
										

									
									
									

									// Update all index structures.	
									

									
									//update the bit vector list
									//Update the sha1 structure list.
									//update the filenamelist

									   char fileID[20];
									  unsigned char *buff1;
									char* msg = (char*)"file";

									//printf("NodeID is %s\n",nodeInstanceId);
									
									buff1=GetUOID((char *)nodeInstanceId,msg,buf, sizeof(buf));
									memcpy(&fileID[0],&buf[0],20);
									/*printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
									printf("File ID is:\n");
									printUOID((unsigned char *)fileID);*/
									// populate bitvector index list
									bitVectorIndexItem indexBVItem;
									memcpy(&indexBVItem.indexBitVector[0],& ptrTagValue[5][0],256);
									indexBVItem.numFileName=numfileId;
									indexBitVectoreList.push_back(indexBVItem);
									
									//populate SHA1 vs numeric name map
									indexSHA1Map.insert(pair<string,int>(string( ptrTagValue[2]),numfileId));
									// populate the numeric name vs fildId map
									numToFileIdMap.insert(pair<int,string>(numfileId,string(fileID)));


									// populate the meta info list.

									indexFileMetaInfo fileMetaInfo;
									memset(&fileMetaInfo.originalFileName[0],'\0',256);
									memcpy(&fileMetaInfo.originalFileName[0],& ptrTagValue[0][0],strlen( ptrTagValue[0]));
									fileMetaInfo.numFileName=numfileId;
									
									memcpy(&fileMetaInfo.fileID[0],&fileID[0],20);
									newfilesize = (int)atoi(ptrTagValue[1]);
									fileMetaInfo.filesize=newfilesize;
									fileMetaInfo.isInCache=true;
									remainingCacheSizeInBytes=remainingCacheSizeInBytes-fileMetaInfo.filesize;
									char randFilePassword[21];
									memset(&randFilePassword[0],'\0',21);
									memcpy(&fileMetaInfo.filePassword[0],&randFilePassword[0],20);
									memcpy(&fileMetaInfo.fileNonceValue[0],& ptrTagValue[3][0],40);
									
									indexFileMetaInfoList.push_back(fileMetaInfo);

									
							}
							pthread_mutex_unlock(&indexMutex);
							if (readMsgHeader.ttlInHeader > 0)
							{
									//Iterate over the connectedNeighbourList
									pthread_mutex_lock(&connectedNodeListMutex);
									queueItem writeQueueItem;
									map<string,int>::iterator conNodeListIterator;
									for ( conNodeListIterator=connectedNodeList.begin() ; conNodeListIterator != connectedNodeList.end(); conNodeListIterator++ )
									{
											float coinflip = drand48();
								//			printf("CoinFlip %f NeighbourProb %f\n",coinflip,neighbourStoreProb);
											if (coinflip > neighbourStoreProb) // If coinflip is greater than neighbourStoreProb then don't forward to that neighbour
											{
												continue; 
											}

											//flood message to all the nodes
											
											//create itemQueue packet
											memset(&writeQueueItem,0,sizeof(queueItem));

											//fill the packet header
											writeQueueItem.msgHeader = readMsgHeader;

											//fill the packet data(that is file name)
											
											if(isStored)
											{
												writeQueueItem.dataBuf[0] = (char)(numfileId);
												writeQueueItem.dataBuf[1] = (char)' ';
												writeQueueItem.dataBuf[2] = (char)'0';
											}
											else
											{	writeQueueItem.dataBuf[0] = (char)(temptempFileId);
												writeQueueItem.dataBuf[1] = (char)' ';
												writeQueueItem.dataBuf[2] = (char)'1';
											}
											//writeQueueItem.dataBuf[1] = count;			/*This is for counting semaphore. Here give index to the write thread which will be decremented there.*/
											//writeQueueItem.sockfd=-1;
											//writeQueueItem.msgHeader.messageType=0xF6;
							//				printf("READ THREAD STORE: Queueitem header is :\n");
							/*				printf("r STRS %d 0x%02x %x%x%x%x %x\n",
															(writeQueueItem.msgHeader.msgDataLength+27),
															(unsigned char)writeQueueItem.msgHeader.ttlInHeader,
															(unsigned char)writeQueueItem.msgHeader.UOID[16],
															(unsigned char)writeQueueItem.msgHeader.UOID[17],
															(unsigned char)writeQueueItem.msgHeader.UOID[18],
															(unsigned char)writeQueueItem.msgHeader.UOID[19],
															(unsigned char)writeQueueItem.dataBuf[0]);
							*/				
											
											//push into write queue
											// write into the appropriate write index
											//uint16_t portTemp=0;
											//char *tempHost=(char*)malloc(512);
												//printf("---------------5--------------\n");
												int socket=(*conNodeListIterator).second;
												//printf("---------------5--------------%d\n",socket);
													//printf("---------------6--------------\n");
													pthread_mutex_lock(&sockIndexMapMutex);
													int index=sockFDToQIndexMap[socket];
														pthread_mutex_lock(&wrtieQMutex[index]);
							//								printf("READ THREAD STORE: Will push %s data in queue.\n\n",writeQueueItem.dataBuf);
															wrtieThreadQueue[index].push_back(writeQueueItem);
							//								printf("READ THREAD STORE: STORE MSG: Msg pushed to writeQueue of %d\n",index);
															pthread_cond_broadcast(&wrtieQCV[index]);

														pthread_mutex_unlock(&wrtieQMutex[index]);								
													pthread_mutex_unlock(&sockIndexMapMutex);




									//pthread_mutex_lock(&connectedNodeListMutex);
									uint16_t portTemp=0;
									char *tempHost=(char*)malloc(512);

							
								
												char* str1 = (char*) malloc(512); 
												memset(&str1[0],'\0',512);
												memcpy(&str1[0],&(((*conNodeListIterator).first).c_str()[0]),19);

												char *str=(char*)malloc(512);
												memset(str,'\0',512);
												memcpy(&str[0],&str1[0],strlen(str1));
												//printf("String from list is %s\n",str);
												
												tempHost=strtok(str,"_");
												//printf("TempHost is %s and length is %d\n",tempHost,(int)strlen(tempHost));
												char *tempPort=strtok(NULL,"_");
												//printf("TempPort is %s and length is %d\n",tempPort,(int)strlen(tempPort));
												
												portTemp=atoi(tempPort);
						
									
								
							///pthread_mutex_unlock(&connectedNodeListMutex);

									pthread_mutex_lock(&logFileMutex);

										gettimeofday(&tv, NULL); 
										int sec = tv.tv_sec ;
										int msec = tv.tv_usec/1000;
										char *time = (char *)malloc(14);
										memset(time,0,14);
										sprintf(time,"%10ld.%03d",(long)sec,msec);
										time[strlen(time)]='\0';

										



										fprintf(logFilePtr, "f  %s %s:%hu STOR %d 0x%02x %x%x%x%x \n",time,
											tempHost,
											portTemp,
											(writeQueueItem.msgHeader.msgDataLength+27),
											(unsigned char)writeQueueItem.msgHeader.ttlInHeader,
											(unsigned char)writeQueueItem.msgHeader.UOID[16],
											(unsigned char)writeQueueItem.msgHeader.UOID[17],
											(unsigned char)writeQueueItem.msgHeader.UOID[18],
											(unsigned char)writeQueueItem.msgHeader.UOID[19]);
											//helloRecvData.HostPort,helloRecvData.Hostname);
										pthread_mutex_unlock(&logFileMutex);











									}
									pthread_mutex_unlock(&connectedNodeListMutex);
									








									
							}
	
						}
						remove(tempDataFile);
						remove(tempMetaFile);
				//	printf("File recieve success.\n");
				}
				else
				 {

					
					if(readMsgHeader.msgDataLength<=MAXFILEBUF)
						{
							int retdata=(int)recv(socketDesc,&readBuf,readMsgHeader.msgDataLength,0);
							if(retdata<0)
							{
							}
							//printf("MetaLength is %X%X%X%X\n",readBuf[0],readBuf[1],readBuf[2],readBuf[3]);
							//printf("%s\n\n\n\n",readBuf);
							memset(&readBuf[0],'\0',MAXFILEBUF);
						}
					else
					{
						int numberOfSegments = ceil((double)(readMsgHeader.msgDataLength)/MAXFILEBUF);
							
							int remainingDataToBeRead = readMsgHeader.msgDataLength;
					//		bool firstPacket=false;
							//printf("Number of segments:%d\n",numberOfSegments);
							for(int i=0;i<numberOfSegments;i++)
							{
								int bytesToBeRead;
								if (remainingDataToBeRead > MAXFILEBUF)
								{
									bytesToBeRead = MAXFILEBUF;
									remainingDataToBeRead = remainingDataToBeRead - MAXFILEBUF;
								}
								else
									bytesToBeRead = remainingDataToBeRead;

								memset(&readBuf[0],0x00,MAXFILEBUF);
								int retdata=(int)recv(socketDesc,&readBuf,bytesToBeRead,0);
								if(retdata<0)
								{
								}
								memset(&readBuf[0],'\0',MAXFILEBUF);
							}
					}

					//printf("Packet Dropped on %d \n",socketDesc);

					pthread_mutex_unlock(&UOIDMsgLifeTimeMapMutex);
					continue;
				}
			}
			else if(readMsgHeader.messageType==0xF8)
			{

				pthread_mutex_lock(&connectedNodeListMutex);
				uint16_t portTemp=0;
				char *tempHost=(char*)malloc(512);
				map<string,int>::iterator it;
				for(it=connectedNodeList.begin() ; it != connectedNodeList.end(); it++ )
				{
					if((*it).second==socketDesc)
					{
								char* str1 = (char*) malloc(512); 
								memset(&str1[0],'\0',512);
								memcpy(&str1[0],&(((*it).first).c_str()[0]),19);

								char *str=(char*)malloc(512);
								memset(str,'\0',512);
								memcpy(&str[0],&str1[0],strlen(str1));
								//printf("String from list is %s\n",str);
								
								tempHost=strtok(str,"_");
								//printf("TempHost is %s and length is %d\n",tempHost,(int)strlen(tempHost));
								char *tempPort=strtok(NULL,"_");
								//printf("TempPort is %s and length is %d\n",tempPort,(int)strlen(tempPort));
								
								portTemp=atoi(tempPort);
								break;
					}
				
				}
				pthread_mutex_unlock(&connectedNodeListMutex);


				pthread_mutex_lock(&logFileMutex);

				gettimeofday(&tv, NULL); 
				int sec = tv.tv_sec ;
				int msec = tv.tv_usec/1000;
				char *time = (char *)malloc(14);
				memset(time,0,14);
				sprintf(time,"%10ld.%03d",(long)sec,msec);
				time[strlen(time)]='\0';

				



				fprintf(logFilePtr, "r  %s %s:%hu KPAV 27 0x%02x %x%x%x%x \n",time,
					tempHost,
					portTemp,
					//(beaconAcceptHeader.msgDataLength+27),
					(unsigned char)readMsgHeader.ttlInHeader,
					(unsigned char)readMsgHeader.UOID[16],
					(unsigned char)readMsgHeader.UOID[17],
					(unsigned char)readMsgHeader.UOID[18],
					(unsigned char)readMsgHeader.UOID[19]);
					//helloRecvData.HostPort,helloRecvData.Hostname);
				pthread_mutex_unlock(&logFileMutex);
			}
			/*else
			{
				continue;
			}*/

			




			if((readMsgHeader.messageType!=0xCC) && (readMsgHeader.messageType!=0xDB))
			{
			
			if(readMsgHeader.msgDataLength!=0)
			{
				char readBuf[512];
				memset(readBuf,0,512);
				int retdata=(int)recv(socketDesc,&readBuf,readMsgHeader.msgDataLength,0);
				if(retdata<0)
				{
						//printf("----------------------ERROR: error in recieveing join response in ReadThread.\n");
						//TODO: Do error Handling here..
						
						//check message push
						if(!iAmBeacon)
						{
							queueItem statusReqToBePushed;
							statusReqToBePushed.sockfd=-1;
							statusReqToBePushed.msgHeader.messageType=0xF6;

							unsigned char *buff1;
							char* msg = (char*)"CKRQ";

							buff1=GetUOID((char *)nodeInstanceId,msg,buf, sizeof(buf));
							memcpy(&(statusReqToBePushed.msgHeader.UOID[0]),&buf[0],20);

							statusReqToBePushed.msgHeader.ttlInHeader=ttl;
							statusReqToBePushed.msgHeader.msgDataLength=0;

							//memcpy(&(statusReqToBePushed.dataBuf[0]),&(statusData.statusType),statusReqToBePushed.msgHeader.msgDataLength);

							if(noCheck==0)
							{
							pthread_mutex_lock(&eventQueueMutex);


							eventQueue.push_back(statusReqToBePushed);
							//printf("EVENT DISPATCHER:CHECK MSG Pushed to Event Dispatcher.\n");
							pthread_cond_broadcast(&eventQueueCV);


							pthread_mutex_unlock(&eventQueueMutex);
							//check timeout thread start
							pthread_create(&checkTimeOut,NULL,checkTimeOutThread,NULL);
						
							//join this thread
							pthread_join(checkTimeOut,NULL);
							}
						}

						//check timeout thread start
						//join this thread
						
						pthread_exit(NULL);
				}
				//printf("READ msgtype %x==> %s in %d.\n\n",readMsgHeader.messageType,readBuf,socketDesc);
				
				//Push the new populated msg to the event dispatcher queue.
				pthread_mutex_lock(&eventQueueMutex);
					
					queueItem newMsgToBePushed;
					newMsgToBePushed.sockfd=socketDesc;
					newMsgToBePushed.msgHeader=readMsgHeader;
					memcpy(&(newMsgToBePushed.dataBuf[0]),&readBuf[0],readMsgHeader.msgDataLength);
					eventQueue.push_back(newMsgToBePushed);
					//printf("Read Thread:MSG Pushed to Event Dispatcher.\n");
					pthread_cond_broadcast(&eventQueueCV);

				pthread_mutex_unlock(&eventQueueMutex);
			}
			}
			/*else
			{
				


				if(readMsgHeader.messageType==0xF8)
				{
					printf("READ THREAD: Keep Alive Detected at read thread %d.\n",socketDesc);
					





				}
				else
				{
					printf("READ THREAD: Other msg detected in Read Thread of %d.\n",socketDesc);
				}

	










			}
			*/



	}//end of while			




}
